package org.onejava.db;

import java.io.IOException;  
import java.io.InputStream;
import java.sql.Connection;  
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;  

import javax.sql.DataSource;  

import org.apache.commons.dbcp.BasicDataSource;  
public class DbcpConnection {  
    private  static DataSource dataSource;
    
      
    public static void initDataSource() throws Exception{  
    	InputStream is = null;  
        Properties properties = new Properties();  
          
        String driverClassName = null;  
        String url = null;  
        String username = null;  
        String password = null;  
          
        int initialSize = 0;  
        int minIdle = 0;  
        int maxIdle = 0;  
        int maxWait = 0;  
        int maxActive = 0;  
          
        try {  
    		is = DbcpConnection.class.getResourceAsStream("/JDBC.properties");
            properties.load(is);  
            driverClassName = properties.getProperty("driver");  
            url = properties.getProperty("url");  
            username = properties.getProperty("username");  
            password = properties.getProperty("password");  
            initialSize = Integer.parseInt((properties.getProperty("initialSize").trim()));  
            minIdle = Integer.parseInt((properties.getProperty("minIdle")).trim());  
            maxIdle = Integer.parseInt((properties.getProperty("maxIdle")).trim());  
            maxWait = Integer.parseInt((properties.getProperty("maxWait")).trim());  
            maxActive = Integer.parseInt((properties.getProperty("maxActive")).trim());  
              
        } catch (Exception e){  
        	throw new Exception(e); 
        }finally{  
            try {  
                is.close();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block
            	throw new Exception(e);
            }  
        }  
        BasicDataSource bds = new BasicDataSource();  
          
        bds.setUrl(url);  
        bds.setDriverClassName(driverClassName);  
        bds.setUsername(username);  
        bds.setPassword(password);  
        bds.setInitialSize(initialSize);  
        bds.setMaxActive(maxActive);  
        bds.setMinIdle(minIdle);  
        bds.setMaxIdle(maxIdle);  
        bds.setMaxWait(maxWait);
        bds.setRemoveAbandoned(true);
        bds.setRemoveAbandonedTimeout(60);
        bds.setLogAbandoned(true);
          
        dataSource = bds;  
    } 
    
    public static Map<String, Integer> printDataSourceStats(){ 
    	Map<String, Integer> map =new HashMap<String, Integer>();
		if(null==dataSource){
			return map;
		}
       BasicDataSource bds2 = (BasicDataSource) dataSource;
       
       map.put("NumActive", bds2.getNumActive());
       map.put("NumIdle", bds2.getNumIdle());
       return map;  
    }
    
    /**
     * 获取链接，如果数据源未加载，会抛出错误
     * @return
     * @throws Exception
     */
    public static Connection getSimpleConnection() throws Exception{
    	if (dataSource == null) {
    		throw new Exception("DataSource may not have been initialized");
    	}else{
    		return dataSource.getConnection(); 
    	}
    }
    
    
    /**
     * 获取一个Connection，如没数据源未加载则加载数据源
     * 
     * 使用双重检查加锁，并不完全安全，但对程序正常运行并无影响，框架最终不使用本方法
     * 
     * @return
     * @throws Exception
     */
    public static Connection  getConnection() throws  Exception {  
        if (dataSource == null) {
        	synchronized (DbcpConnection.class) {
        		if (dataSource == null) {
                    initDataSource();     
        		}
			}
        }     
        Connection conn = null;     
        if (dataSource != null) {     
            conn = dataSource.getConnection();     
        }     
        return conn;     
    }  
}  